//--------------------------------------------------------------------------------------------------------------
// <copyright file="XslRenderer.cs" company="Microsoft Corporation" author="David Martos" date="01/01/2007">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//--------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace CSP.Core
{
    /// <summary>
    /// Class to render XML information into HTML output using a XSL stylesheet. XML data
    /// is cached internally in a MemoryStream and finally xslt-transformed 
    /// </summary>
    public class XslRenderer : XmlTextWriter
    {

        HtmlTextWriter _output;
        ContentPlaceHolder _ctrl;
        string _xslUri;

        /// <summary>
        /// Create a new XslRenderer object to render XML data
        /// </summary>
        /// <param name="xslUri">Path to XSL stylesheet document</param>
        /// <param name="output">Stream to write the HTML output</param>
        public XslRenderer(string xslUri, HtmlTextWriter output)
            : base(new MemoryStream(), Encoding.Default)
        {
            Errors.InitializeLog();

            _xslUri = xslUri;
            _output = output;
            _ctrl = null;
        }

        /// <summary>
        /// Create a new XslRenderer object to render XML data
        /// </summary>
        /// <param name="xslUri">Path to XSL stylesheet document</param>
        /// <param name="ctrl">ContentPlaceHolder to write the HTML output</param>
        public XslRenderer(string xslUri, ContentPlaceHolder ctrl)
            : base(new MemoryStream(), Encoding.Default)
        {
            Errors.InitializeLog();

            _xslUri = xslUri;
            _output = null;
            _ctrl = ctrl;
        }

        /// <summary>
        /// Write an XML element which content is the output HTML from a Web control
        /// </summary>
        /// <param name="elemName">Element name</param>
        /// <param name="ctrl">Web control</param>
        public void WriteControl(string elemName, Control ctrl)
        {
            try
            {
                MemoryStream memStream = new MemoryStream();
                HtmlTextWriter htw = new HtmlTextWriter(new StreamWriter(memStream));
                ctrl.RenderControl(htw);
                htw.Flush();
                memStream.Position = 0;
                StreamReader sr = new StreamReader(memStream);
                string ctrlHtml = sr.ReadToEnd();
                WriteElementString(elemName, ctrlHtml);
                memStream.Close();
            }
            catch (Exception ex)
            {
                //log.Error(ex.Message, ex);
                throw ex;
            }
        }

        /// <summary>
        /// Close the XslRenderer and flush all XML data into HTML output
        /// </summary>
        public override void Close()
        {
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                Stream baseStream = this.BaseStream;
                if (baseStream == null)
                    throw new Exception("BaseStream is null before closing");

                base.Flush();
                baseStream.Position = 0;

                    SPWeb site = null;
                    SPSite webCollection = SPControl.GetContextSite(HttpContext.Current);
                    SPSite rootSite = new SPSite(webCollection.Url);


                    site = rootSite.OpenWeb();


                    SPFolder folder = site.GetFolder(_xslUri.Substring(0, _xslUri.LastIndexOf("/")));

                    SPFile file = folder.Files[_xslUri.Substring(_xslUri.LastIndexOf("/") + 1)]; // site.GetFile(_xslUri);
                    using (Stream xslStream = file.OpenBinaryStream())
                    {
                        XslCompiledTransform xslt = new XslCompiledTransform();
                        xslt.Load(new XmlTextReader(xslStream));

                        if (_output != null)
                        {
                            xslt.Transform(new XmlTextReader(baseStream), new XmlTextWriter(_output));
                        }

                        if (_ctrl != null)
                        {
                            using (MemoryStream memStream = new MemoryStream())
                            {
                                xslt.Transform(new XmlTextReader(baseStream), new XmlTextWriter(memStream, Encoding.Default));
                                memStream.Position = 0;
                                string xml = new StreamReader(memStream).ReadToEnd();
                                _ctrl.Controls.Add(new LiteralControl(xml));
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
//                log.Error(ex.Message, ex);
                throw ex;
            }
            finally
            {
                base.Close();
            }
        }
    }
}
